import numpy as np
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score
'''''
# 加载鸢尾花数据集
iris = datasets.load_iris()
X = iris.data  # 特征数据
y = iris.target  # 标签数据

# 划分数据集为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# 创建KNN分类器实例
knn = KNeighborsClassifier(n_neighbors=3)

# 训练KNN模型
knn.fit(X_train, y_train)

# 使用模型进行预测
y_pred = knn.predict(X_test)

# 计算预测准确率
accuracy = accuracy_score(y_test, y_pred)
print(f"KNN分类器的预测准确率：{accuracy:.2f}")
'''
# ==================== （1）数据准备与预处理 ====================
# 加载鸢尾花数据集
iris = datasets.load_iris()
X = iris.data  # 特征数据（花瓣长度、宽度，萼片长度、宽度）
y = iris.target  # 标签数据（0:山鸢尾，1:杂色鸢尾，2:维吉尼亚鸢尾）

# 数据检查：确保数据完整性和有效性
print("===== 数据基本信息 =====")
print("特征数据形状（样本数，特征数）:", X.shape)  # 应输出 (150, 4)
print("标签数据形状（样本数，）:", y.shape)        # 应输出 (150,)
print("\n前5个样本的特征数据：\n", X[:5])          # 查看前5个样本特征
print("\n前5个样本的标签数据：", y[:5])            # 查看前5个样本标签
print("\n是否存在缺失值（特征）:", np.isnan(X).any())  # 检查特征缺失值（应为False）
print("是否存在缺失值（标签）:", np.isnan(y).any())    # 检查标签缺失值（应为False）
print("类别分布：", np.bincount(y))                 # 查看类别平衡情况（应为[50,50,50]）

# ==================== （2）数据集划分 ====================
# 划分训练集（70%）和测试集（30%），设置随机种子保证可复现
X_train, X_test, y_train, y_test = train_test_split(
    X, y,
    test_size=0.3,        # 测试集占30%
    random_state=24       # 固定随机种子，确保划分结果一致
)

# 打印划分后数据量验证
print("\n===== 数据集划分结果 =====")
print("训练集样本数:", len(X_train))  # 应输出 105（150 * 0.7）
print("测试集样本数:", len(X_test))   # 应输出 45（150 * 0.3）

# ==================== （3）KNN模型构建与训练 ====================
# 实例化KNN分类器（K=3为经验值，可根据后续调参优化）
knn = KNeighborsClassifier(n_neighbors=3)

# 使用训练集训练模型（KNN本质是惰性学习，训练阶段仅存储数据）
knn.fit(X_train, y_train)

# ==================== （4）模型评估与预测 ====================
# 对测试集进行预测
y_pred = knn.predict(X_test)

# 计算预测准确率（正确预测样本数/总测试样本数）
accuracy = accuracy_score(y_test, y_pred)
print(f"\n===== 模型评估结果 =====")
print(f"KNN分类器（K=3）的预测准确率：{accuracy:.4f}")  # 输出保留4位小数更精确